/**
 * @author nttdocomo
 */
define(function(require) {
	require("../../aries");
	require("./base");
	require("../checkboxManager");
	/**
	 Creates a new form field checkbox.
	 @class Represents a field of basic.
	 @param {Object} options
	 */
	aries.klass("aries.form.field.Checkbox", aries.form.field.Base.extend({
		boxLabelCls : aries.baseCSSPrefix + 'form-cb-label',
		boxLabelAlign : 'after',
		inputType : 'checkbox',

		/**
		 * @cfg {Boolean} checked
		 * true if the checkbox should render initially checked
		 */
		checked : false,

		/**
		 * @cfg {String} inputValue
		 * The value that should go into the generated input element's value attribute and should be used as the parameter
		 * value when submitting as part of a form.
		 */
		inputValue : 'on',

		/**
		 * @cfg {String} [checkedCls='x-form-cb-checked']
		 * The CSS class added to the component's main element when it is in the checked state.
		 */
		checkedCls : aries.baseCSSPrefix + 'form-cb-checked',

		// private
		onRe : /^on$/i,

		initComponent : function() {
			aries.form.field.Base.prototype.initComponent.apply(this, arguments);
			this.getManager().add(this);
		},
		fieldSubTpl : ['<input type="button" id="<%=id%>"', '<% if(typeof(tabIdx)!=="undefined"){%> tabIndex="<%=tabIdx%>"<%}%>', '<% if(disabled){%> disabled="disabled"<%}%>', '<% if(typeof(fieldStyle)!=="undefined"){%> style="<%=fieldStyle%>"<%}%>', ' class="<%=fieldCls%> <%=typeCls%>" autocomplete="off" hidefocus="true" />', '<% if(typeof(boxLabel)!=="undefined" && boxLabelAlign == "after"){%>', '<label id="<%=cmpId%>-boxLabelEl" class="<%=boxLabelCls%> <%=boxLabelCls%>-<%=boxLabelAlign%>" for="<%=id%>">', '<%=boxLabel%>', '</label>', '<%}%>'].join(""),

		getElConfig : function() {
			var me = this;

			// Add the checked class if this begins checked
			if (me.isChecked(me.rawValue, me.inputValue)) {
				me.addCls(me.checkedCls);
			}
			return aries.form.field.Base.prototype.getElConfig.apply(this, arguments);
		},

		getFormId : function() {
			var me = this, form;

			if (!me.formId) {
				form = me.up('form');
				if (form) {
					me.formId = form.id;
				}
			}
			return me.formId;
		},

		// inherit docs
		getManager : function() {
			if(this.Manager)
				return this.Manager;
			return this.Manager = new aries.form.CheckboxManager;
		},

		/**
		 * Returns the checked state of the checkbox.
		 * @return {Boolean} True if checked, else false
		 */
		getRawValue : function() {
			return this.checked;
		},
		getSubTplData : function() {
			return $.extend(aries.form.field.Base.prototype.getSubTplData.apply(this, []), {
				disabled : this.readOnly || this.disabled,
				boxLabel : this.boxLabel,
				checked : this.checked,
				boxLabelCls : this.boxLabelCls,
				boxLabelAlign : this.boxLabelAlign
			});
		},

		/**
		 * Returns the submit value for the checkbox which can be used when submitting forms.
		 * @return {String} If checked the {@link #inputValue} is returned; otherwise the {@link #uncheckedValue}
		 * (or null if the latter is not configured).
		 */
		getSubmitValue : function() {
			var unchecked = this.uncheckedValue, uncheckedVal = !_.isUndefined(unchecked) ? unchecked : null;
			return this.checked ? this.inputValue : uncheckedVal;
		},

		/**
		 * Returns the checked state of the checkbox.
		 * @return {Boolean} True if checked, else false
		 */
		getValue : function() {
			return this.checked;
		},

		initEvents : function() {
			var me = this;
			aries.form.field.Base.prototype.initEvents.apply(this, arguments);
			$.extend(this.events, {
				"click input" : "onBoxClick"
			})
		},

		initValue : function() {
			var me = this, checked = !!me.checked;

			/**
			 * @property {Object} originalValue
			 * The original value of the field as configured in the {@link #checked} configuration, or as loaded by the last
			 * form load operation if the form's {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} setting is `true`.
			 */
			me.originalValue = me.lastValue = checked;

			// Set the initial checked state
			me.setValue(checked);
		},

		isChecked : function(rawValue, inputValue) {
			return (rawValue === true || rawValue === 'true' || rawValue === '1' || rawValue === 1 || (((_.isString(rawValue) || _.isNumber(rawValue)) && inputValue) ? rawValue == inputValue : this.onRe.test(rawValue)));
		},

		/**
		 * @private Handle click on the checkbox button
		 */
		onBoxClick : function(e) {
			var me = this;
			if (!me.disabled && !me.readOnly) {
				this.setValue(!this.checked);
			}
		},

		/**
		 * Sets the checked state of the checkbox.
		 *
		 * @param {Boolean/String/Number} value The following values will check the checkbox:
		 * `true, 'true', '1', 1, or 'on'`, as well as a String that matches the {@link #inputValue}.
		 * Any other value will uncheck the checkbox.
		 * @return {Boolean} the new checked state of the checkbox
		 */
		setRawValue : function(value) {
			var me = this, inputEl = me.inputEl, checked = me.isChecked(value, me.inputValue);

			if (inputEl) {
				me[checked ? 'addCls' : 'removeCls'](me.checkedCls);
			}

			me.checked = me.rawValue = checked;
			return checked;
		},

		/**
		 * Sets the checked state of the checkbox, and invokes change detection.
		 * @param {Boolean/String} checked The following values will check the checkbox: `true, 'true', '1', or 'on'`, as
		 * well as a String that matches the {@link #inputValue}. Any other value will uncheck the checkbox.
		 * @return {Ext.form.field.Checkbox} this
		 */
		setValue : function(checked) {
			var me = this, boxes, i, len, box;

			// If an array of strings is passed, find all checkboxes in the group with the same name as this
			// one and check all those whose inputValue is in the array, unchecking all the others. This is to
			// facilitate setting values from Ext.form.Basic#setValues, but is not publicly documented as we
			// don't want users depending on this behavior.
			if (_.isArray(checked)) {
				boxes = me.getManager().getByName(me.name, me.getFormId()).items;
				len = boxes.length;

				for ( i = 0; i < len; ++i) {
					box = boxes[i];
					box.setValue(_.indexOf(checked, box.inputValue) > -1);
				}
			} else {
				aries.form.field.Base.prototype.setValue.apply(this, arguments);
			}

			return me;
		}
	}, {
		xtype : 'checkboxfield'
	}))
})
